// React Hook 用于防止内存泄漏

import { useEffect, useRef, useCallback } from 'react';
import { memoryMonitorService } from '../services/memoryMonitor';

/**
 * 防止事件监听器泄漏的 Hook
 */
export function useSafeEventListener<T extends Event>(
  element: Element | Window | null,
  eventType: string,
  handler: (event: T) => void,
  options?: boolean | AddEventListenerOptions
): void {
  const handlerRef = useRef<(event: T) => void>();
  const elementName = element === window ? 'window' : (element?.tagName || 'unknown');

  // 更新处理函数引用
  handlerRef.current = handler;

  useEffect(() => {
    if (!element) return;

    // 包装处理函数以保持引用稳定
    const eventHandler = (event: Event) => {
      handlerRef.current?.(event as T);
    };

    // 添加事件监听器
    element.addEventListener(eventType, eventHandler, options);
    
    // 追踪事件监听器
    memoryMonitorService.trackEventListener(elementName, eventType);

    // 清理函数
    return () => {
      element.removeEventListener(eventType, eventHandler, options);
      memoryMonitorService.untrackEventListener(elementName, eventType);
    };
  }, [element, eventType, options, elementName]);
}

/**
 * 防止定时器泄漏的 Hook
 */
export function useSafeInterval(
  callback: () => void,
  delay: number | null,
  immediate?: boolean
): {
  start: () => void;
  stop: () => void;
  isRunning: boolean;
} {
  const callbackRef = useRef<() => void>();
  const intervalRef = useRef<NodeJS.Timeout>();
  const isRunningRef = useRef<boolean>(false);

  // 更新回调函数引用
  callbackRef.current = callback;

  const start = useCallback(() => {
    if (isRunningRef.current || delay === null) return;

    if (immediate) {
      callbackRef.current?.();
    }

    const timer = setInterval(() => {
      callbackRef.current?.();
    }, delay);

    intervalRef.current = timer;
    isRunningRef.current = true;
    memoryMonitorService.trackTimer(timer);
  }, [delay, immediate]);

  const stop = useCallback(() => {
    if (intervalRef.current) {
      clearInterval(intervalRef.current);
      memoryMonitorService.untrackTimer(intervalRef.current);
      intervalRef.current = undefined;
      isRunningRef.current = false;
    }
  }, []);

  useEffect(() => {
    if (delay !== null) {
      start();
    }

    return stop;
  }, [delay, start, stop]);

  return {
    start,
    stop,
    isRunning: isRunningRef.current
  };
}

/**
 * 防止 setTimeout 泄漏的 Hook
 */
export function useSafeTimeout(
  callback: () => void,
  delay: number | null
): {
  start: () => void;
  stop: () => void;
  isActive: boolean;
} {
  const callbackRef = useRef<() => void>();
  const timeoutRef = useRef<NodeJS.Timeout>();
  const isActiveRef = useRef<boolean>(false);

  callbackRef.current = callback;

  const start = useCallback(() => {
    if (isActiveRef.current || delay === null) return;

    const timer = setTimeout(() => {
      callbackRef.current?.();
      memoryMonitorService.untrackTimer(timer);
      isActiveRef.current = false;
    }, delay);

    timeoutRef.current = timer;
    isActiveRef.current = true;
    memoryMonitorService.trackTimer(timer);
  }, [delay]);

  const stop = useCallback(() => {
    if (timeoutRef.current) {
      clearTimeout(timeoutRef.current);
      memoryMonitorService.untrackTimer(timeoutRef.current);
      timeoutRef.current = undefined;
      isActiveRef.current = false;
    }
  }, []);

  useEffect(() => {
    if (delay !== null) {
      start();
    }

    return stop;
  }, [delay, start, stop]);

  return {
    start,
    stop,
    isActive: isActiveRef.current
  };
}

/**
 * 组件生命周期追踪 Hook
 */
export function useComponentTracking(componentName: string): void {
  useEffect(() => {
    // 组件挂载时注册
    memoryMonitorService.trackComponent(componentName);
    console.log(`[组件追踪] ${componentName} 组件已挂载`);

    // 组件卸载时注销
    return () => {
      memoryMonitorService.untrackComponent(componentName);
      console.log(`[组件追踪] ${componentName} 组件已卸载`);
    };
  }, [componentName]);
}

/**
 * 防止异步操作泄漏的 Hook
 */
export function useSafeAsync<T>(): {
  execute: (asyncFn: () => Promise<T>) => Promise<T | null>;
  cancel: () => void;
  isActive: boolean;
} {
  const isMountedRef = useRef<boolean>(true);
  const activePromisesRef = useRef<Set<Promise<any>>>(new Set());

  const execute = useCallback(async <T>(asyncFn: () => Promise<T>): Promise<T | null> => {
    if (!isMountedRef.current) {
      console.warn('[异步操作] 组件已卸载，取消异步操作');
      return null;
    }

    const promise = asyncFn();
    activePromisesRef.current.add(promise);

    try {
      const result = await promise;
      activePromisesRef.current.delete(promise);
      
      // 检查组件是否仍然挂载
      if (isMountedRef.current) {
        return result;
      } else {
        console.warn('[异步操作] 组件已卸载，忽略异步操作结果');
        return null;
      }
    } catch (error) {
      activePromisesRef.current.delete(promise);
      if (isMountedRef.current) {
        throw error;
      } else {
        console.warn('[异步操作] 组件已卸载，忽略异步操作错误');
        return null;
      }
    }
  }, []);

  const cancel = useCallback(() => {
    isMountedRef.current = false;
    activePromisesRef.current.clear();
  }, []);

  useEffect(() => {
    return () => {
      cancel();
    };
  }, [cancel]);

  return {
    execute,
    cancel,
    isActive: isMountedRef.current
  };
}

/**
 * 防止状态更新泄漏的 Hook
 */
export function useSafeState<T>(
  initialState: T | (() => T)
): [T, (value: T | ((prev: T) => T)) => void] {
  const [state, setState] = React.useState<T>(initialState);
  const isMountedRef = useRef<boolean>(true);

  const safeSetState = useCallback((value: T | ((prev: T) => T)) => {
    if (isMountedRef.current) {
      setState(value);
    } else {
      console.warn('[状态更新] 组件已卸载，取消状态更新');
    }
  }, []);

  useEffect(() => {
    return () => {
      isMountedRef.current = false;
    };
  }, []);

  return [state, safeSetState];
}

/**
 * 内存使用监控 Hook
 */
export function useMemoryMonitor(
  enabled: boolean = true
): {
  memoryInfo: MemoryInfo | null;
  isMonitoring: boolean;
  startMonitoring: () => void;
  stopMonitoring: () => void;
} {
  const [memoryInfo, setMemoryInfo] = useSafeState<MemoryInfo | null>(null);
  const [isMonitoring, setIsMonitoring] = useSafeState<boolean>(false);

  const startMonitoring = useCallback(() => {
    if (!isMonitoring) {
      memoryMonitorService.startMonitoring(1000);
      setIsMonitoring(true);
    }
  }, [isMonitoring, setIsMonitoring]);

  const stopMonitoring = useCallback(() => {
    if (isMonitoring) {
      memoryMonitorService.stopMonitoring();
      setIsMonitoring(false);
    }
  }, [isMonitoring, setIsMonitoring]);

  useEffect(() => {
    if (!enabled) return;

    const listener = (info: MemoryInfo) => {
      setMemoryInfo(info);
    };

    memoryMonitorService.addListener(listener);

    return () => {
      memoryMonitorService.removeListener(listener);
    };
  }, [enabled, setMemoryInfo]);

  useEffect(() => {
    if (enabled) {
      startMonitoring();
    }

    return () => {
      if (enabled) {
        stopMonitoring();
      }
    };
  }, [enabled, startMonitoring, stopMonitoring]);

  return {
    memoryInfo,
    isMonitoring,
    startMonitoring,
    stopMonitoring
  };
}

/**
 * 自动清理资源的 Hook
 */
export function useAutoCleanup(
  cleanup: () => void,
  deps: React.DependencyList = []
): void {
  const cleanupRef = useRef<() => void>();
  cleanupRef.current = cleanup;

  useEffect(() => {
    return () => {
      cleanupRef.current?.();
    };
  }, deps);
}

/**
 * 防止闭包泄漏的 Hook
 */
export function useStableCallback<T extends (...args: any[]) => any>(
  callback: T
): T {
  const callbackRef = useRef<T>();
  callbackRef.current = callback;

  const stableCallback = useCallback((...args: any[]) => {
    return callbackRef.current?.(...args);
  }, []) as T;

  return stableCallback;
}

import React from 'react';
import { MemoryInfo } from '../services/memoryMonitor';